package com.crm.framework.shiro.realm;

import com.crm.model.entity.sys.UserAccount;
import com.crm.service.sys.UserAccountDbService;
import org.apache.shiro.SecurityUtils;
import org.apache.shiro.authc.*;
import org.apache.shiro.authz.AuthorizationInfo;
import org.apache.shiro.realm.AuthorizingRealm;
import org.apache.shiro.subject.PrincipalCollection;
import org.apache.shiro.util.ByteSource;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.redis.core.StringRedisTemplate;

/**
 /**
 * 自定义Realm 处理登录 权限
 * @author
 */
public class UserRealm extends AuthorizingRealm
{
    @Autowired
    private UserAccountDbService userAccountDbService;

    @Autowired
    private StringRedisTemplate redisTemplate;

    @Override
    protected AuthorizationInfo doGetAuthorizationInfo(PrincipalCollection principalCollection) {
        return null;
    }

    /**
     * 登录认证
     */
    @Override
    protected AuthenticationInfo doGetAuthenticationInfo(AuthenticationToken token) throws AuthenticationException
    {
        UsernamePasswordToken upToken = (UsernamePasswordToken) token;
        String userAccount = upToken.getUsername();
        String password = "";
        if (upToken.getPassword() != null)
        {
            password = new String(upToken.getPassword());
        }
        try {
            UserAccount account = userAccountDbService.selectUserAccountByUserAccount(userAccount);
            if ("无需密码直接登录".equals(upToken.getHost())) {//企业微信扫码登录
                //无需密码直接登录 MD5 2次加密后
                String passwordMD5 = "2f9249e443bab11d29986ae90b454b17";
                SimpleAuthenticationInfo info = new SimpleAuthenticationInfo(account, //需实现Serializable接口,否则报错
                        passwordMD5, //密码
                        ByteSource.Util.bytes("789"),///salt 盐
                        getName());//realmName
                return info;
             } else if (account != null) {
                SimpleAuthenticationInfo info = new SimpleAuthenticationInfo(account,//需实现Serializable接口,否则报错
                        account.getUserPassword(),//(数据库中的)密码
                        ByteSource.Util.bytes(account.getSalt()),//salt 盐
                        getName());//realmName

                return info;
            } else {
                return null;//会抛出UnknownAccountException异常
            }
        } catch (RuntimeException e) {
            throw e;
        }
    }

    /**
     * 清理缓存权限
     */
    public void clearCachedAuthorizationInfo()
    {
        this.clearCachedAuthorizationInfo(SecurityUtils.getSubject().getPrincipals());
    }
}
